// Author: wsfuyibing <682805@qq.com>
// Date: 2025-04-14

package gen_model

type MysqlType string

const (
	// Integer

	MysqlTypeBit       MysqlType = "bit"       // [1,64]
	MysqlTypeTinyint   MysqlType = "tinyint"   // [-128,127]
	MysqlTypeSmallInt  MysqlType = "smallint"  // [-32768,32767]
	MysqlTypeMediumInt MysqlType = "mediumint" // [-8388608,8388607]
	MysqlTypeInt       MysqlType = "int"       // [-2147483648,2147483647]
	MysqlTypeBigInt    MysqlType = "bigint"    // [-9223372036854775808,9223372036854775807]

	MysqlTypeUTinyint   MysqlType = "utinyint"   // [0,255]
	MysqlTypeUSmallInt  MysqlType = "usmallint"  // [0,65535]
	MysqlTypeUMediumInt MysqlType = "umediumint" // [0,16777215]
	MysqlTypeUInt       MysqlType = "uint"       // [0,4294967295]
	MysqlTypeUBigInt    MysqlType = "ubigint"    // [0,18446744073709551615]

	// Float

	MysqlTypeFloat   MysqlType = "float"
	MysqlTypeDouble  MysqlType = "double"
	MysqlTypeDecimal MysqlType = "decimal"

	// Date & Time

	MysqlTypeDate      MysqlType = "date"      // [1000-01-01, 9999-12-31]
	MysqlTypeDateTime  MysqlType = "datetime"  // [1000-01-01 00:00:00, 9999-12-31 23:59:59]
	MysqlTypeTime      MysqlType = "time"      // [-838:59:59, 838:59:59]
	MysqlTypeTimestamp MysqlType = "timestamp" // [1970-01-01 00:00:00, 2037]
	MysqlTypeYear      MysqlType = "year"      // [0000|1901,2155][70,69]

	// String

	MysqlTypeChar       MysqlType = "char"
	MysqlTypeEnum       MysqlType = "enum"
	MysqlTypeText       MysqlType = "text"
	MysqlTypeVarchar    MysqlType = "varchar"
	MysqlTypeMediumText MysqlType = "mediumtext"
	MysqlTypeLongText   MysqlType = "longtext"

	MysqlTypeBinary     MysqlType = "binary"
	MysqlTypeBlob       MysqlType = "blob"
	MysqlTypeLongBlob   MysqlType = "longblob"
	MysqlTypeMediumBlob MysqlType = "mediumblob"
	MysqlTypeTinyBlob   MysqlType = "tinyblob"

	// MysqlTypeJson               MysqlType = "json"
	// MysqlTypeVarBinary          MysqlType = "varbinary"
	// MysqlTypeSet                MysqlType = "set"
	// MysqlTypeJsonb              MysqlType = "jsonb"
	// MysqlTypeUUID               MysqlType = "uuid"
	// MysqlTypeGeometry           MysqlType = "geometry"
	// MysqlTypeGeometryCollection MysqlType = "geometrycollection"
	// MysqlTypeLineString         MysqlType = "linestring"
	// MysqlTypeMultiLineString    MysqlType = "multilinestring"
	// MysqlTypeMultiPoint         MysqlType = "multipoint"
	// MysqlTypeMultiPolygon       MysqlType = "multipolygon"
	// MysqlTypePoint              MysqlType = "point"
	// MysqlTypePolygon            MysqlType = "polygon"
)

var (
	mysqlTypeSize = map[MysqlType]int{
		// integer

		MysqlTypeBit:       16,
		MysqlTypeTinyint:   1,
		MysqlTypeSmallInt:  1,
		MysqlTypeMediumInt: 2,
		MysqlTypeInt:       4,
		MysqlTypeBigInt:    8,

		MysqlTypeUTinyint:   1,
		MysqlTypeUSmallInt:  1,
		MysqlTypeUMediumInt: 2,
		MysqlTypeUInt:       4,
		MysqlTypeUBigInt:    8,

		// float

		MysqlTypeFloat:   4, // {"float32"},
		MysqlTypeDouble:  8, // {"float64"},
		MysqlTypeDecimal: 8, // {"float64"},

		// date & time

		MysqlTypeDate:      24, // {"framework.MysqlDate", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeDateTime:  24, // {"framework.MysqlDatetime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeTime:      16, // {"framework.MysqlTime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeTimestamp: 24, // {"framework.MysqlDatetime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeYear:      8,  // {"framework.MysqlYear", "gitee.com/go-wares/framework-gin/framework"},

		// []byte

		MysqlTypeBinary:     24,
		MysqlTypeBlob:       24,
		MysqlTypeLongBlob:   24,
		MysqlTypeMediumBlob: 24,
		MysqlTypeTinyBlob:   24,

		// string

		MysqlTypeChar:       16,
		MysqlTypeVarchar:    16,
		MysqlTypeText:       16,
		MysqlTypeEnum:       16,
		MysqlTypeMediumText: 16,
		MysqlTypeLongText:   16,
	}
	mysqlTypeMapping = map[MysqlType][]string{
		// integer

		MysqlTypeBit:       {"framework.MysqlBit", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeTinyint:   {"int8"},
		MysqlTypeSmallInt:  {"int8"},
		MysqlTypeMediumInt: {"int16"},
		MysqlTypeInt:       {"int32"},
		MysqlTypeBigInt:    {"int64"},

		MysqlTypeUTinyint:   {"uint8"},
		MysqlTypeUSmallInt:  {"uint8"},
		MysqlTypeUMediumInt: {"uint16"},
		MysqlTypeUInt:       {"uint32"},
		MysqlTypeUBigInt:    {"uint64"},

		// float

		MysqlTypeFloat:   {"float32"},
		MysqlTypeDouble:  {"float64"},
		MysqlTypeDecimal: {"float64"},

		// date & time

		MysqlTypeDate:      {"framework.MysqlDate", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeDateTime:  {"framework.MysqlDatetime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeTime:      {"framework.MysqlTime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeTimestamp: {"framework.MysqlDatetime", "gitee.com/go-wares/framework-gin/framework"},
		MysqlTypeYear:      {"framework.MysqlYear", "gitee.com/go-wares/framework-gin/framework"},

		// []byte

		MysqlTypeBinary:     {"[]byte"},
		MysqlTypeBlob:       {"[]byte"},
		MysqlTypeLongBlob:   {"[]byte"},
		MysqlTypeMediumBlob: {"[]byte"},
		MysqlTypeTinyBlob:   {"[]byte"},

		// string

		MysqlTypeChar:       {"string"},
		MysqlTypeVarchar:    {"string"},
		MysqlTypeText:       {"string"},
		MysqlTypeEnum:       {"string"},
		MysqlTypeMediumText: {"string"},
		MysqlTypeLongText:   {"string"},
	}
)

func (o MysqlType) IsInteger() bool {
	switch o {
	case MysqlTypeTinyint, MysqlTypeSmallInt, MysqlTypeMediumInt, MysqlTypeInt, MysqlTypeBigInt,
		MysqlTypeUTinyint, MysqlTypeUSmallInt, MysqlTypeUMediumInt, MysqlTypeUInt, MysqlTypeUBigInt:
		return true
	}
	return false
}

func (o MysqlType) Orm() (size int, typ, pkg string) {
	if v, ok := mysqlTypeMapping[o]; ok {
		if n := len(v); n > 0 {
			size = o.Size()
			typ = v[0]
			if n > 1 {
				pkg = v[1]
			}
		}
	}
	return
}

func (o MysqlType) Size() int {
	if n, ok := mysqlTypeSize[o]; ok {
		return n
	}
	return 8
}
